import { createPopper } from "@popperjs/core/lib/popper-lite.js";
// import preventOverflow from "@popperjs/core/lib/modifiers/preventOverflow.js";
// import flip from "@popperjs/core/lib/modifiers/flip.js";
import { on, off, addClass, removeClass } from "@/utils/dom.js";
import Vue from "vue";

export default {
	name: "VTooltip",

	props: {
		openDelay: {
			//延迟出现，单位毫秒
			type: Number,
			default: 0,
		},
		disabled: Boolean, //
		manual: Boolean, //手动控制模式，设置为 true 后，mouseenter 和 mouseleave 事件将不会生效
		effect: {
			//默认提供的主题
			type: String,
			default: "dark",
		},
		arrowOffset: {
			type: Number,
			default: 0,
		},
		popperClass: String, //为 Tooltip 的 popper 添加类名
		content: String, //显示的内容，也可以通过 slot#content 传入 DOM
		visibleArrow: {
			//是否显示 Tooltip 箭头
			default: true,
		},
		transition: {
			//定义渐变动画
			type: String,
			default: "v-fade-in-linear",
		},
		popperOptions: {
			//popper.js 的参数
			default() {
				return {
					boundariesPadding: 10,
					gpuAcceleration: false,
				};
			},
		},
		enterable: {
			//鼠标是否可进入到 tooltip 中
			type: Boolean,
			default: true,
		},
		hideAfter: {
			//Tooltip 出现后自动隐藏延时，单位毫秒，为 0 则不会自动隐藏
			type: Number,
			default: 0,
		},
		tabindex: {
			//Tooltip 组件的 tabindex
			type: Number,
			default: 0,
		},
	},

	data() {
		return {
			tooltipId: `el-tooltip-${this.generateId()}`,
			timeoutPending: null,
			focusing: false,
			showPopper: false, //是否显示
			popperVM: "",
			value: true,
		};
	},
	beforeCreate() {
		this.popperVM = new Vue({
			data: { node: "" },
			render() {
				return this.node;
			},
		}).$mount();
	},

	render() {
		if (this.popperVM) {
			this.popperVM.node = (
				<transition name={this.transition} onAfterLeave={this.doDestroy}>
					<div
						onMouseleave={() => {
							this.setExpectedState(false);
						}}
						onMouseenter={() => {
							this.setExpectedState(true);
						}}
						ref="popper"
						role="tooltip"
						id={this.tooltipId}
						v-show={!this.disabled && this.showPopper}
						class={[
							"el-tooltip__popper",
							"is-" + this.effect,
							this.popperClass,
						]}
					>
						{this.$slots.content || this.content}
					</div>
				</transition>
			);
		}

		const firstElement = this.getFirstElement();
		if (!firstElement) return null;

		const data = (firstElement.data = firstElement.data || {});
		data.staticClass = this.addTooltipClass(data.staticClass);

		return firstElement;
	},

	mounted() {
		this.referenceElm = this.$el;
		if (this.$el.nodeType === 1) {
			this.$el.setAttribute("aria-describedby", this.tooltipId);
			this.$el.setAttribute("tabindex", this.tabindex);
			on(this.referenceElm, "mouseenter", this.show);
			on(this.referenceElm, "mouseleave", this.hide);
			on(this.referenceElm, "focus", () => {
				if (!this.$slots.default || !this.$slots.default.length) {
					this.handleFocus();
					return;
				}
				const instance = this.$slots.default[0].componentInstance;
				if (instance && instance.focus) {
					instance.focus();
				} else {
					this.handleFocus();
				}
			});
			on(this.referenceElm, "blur", this.handleBlur);
			on(this.referenceElm, "click", this.removeFocusing);
		}
		// fix issue https://github.com/ElemeFE/element/issues/14424
		if (this.value) {
			// this.popperVM.$nextTick(() => {
			const hhh = document.createElement("div");
			hhh.innerHTML = "hhahahh";
			if (this.value) {
				createPopper(this.referenceElm, hhh, {});
			}
			// });
		}
	},
	watch: {
		focusing(val) {
			if (val) {
				addClass(this.referenceElm, "focusing");
			} else {
				removeClass(this.referenceElm, "focusing");
			}
		},
	},
	methods: {
		show() {
			console.log(this.showPopper);
			this.showPopper = true;
		},

		hide() {
			this.showPopper = false;
		},
		handleFocus() {
			this.focusing = true;
			this.show();
		},
		handleBlur() {
			this.focusing = false;
			this.hide();
		},
		removeFocusing() {
			this.focusing = false;
		},

		addTooltipClass(prev) {
			if (!prev) {
				return "el-tooltip";
			} else {
				return "el-tooltip " + prev.replace("el-tooltip", "");
			}
		},

		getFirstElement() {
			const slots = this.$slots.default;
			if (!Array.isArray(slots)) return null;
			let element = null;
			for (let index = 0; index < slots.length; index++) {
				if (slots[index] && slots[index].tag) {
					element = slots[index];
				}
			}
			return element;
		},

		doDestroy() {
			/* istanbul ignore if */
			// if (!this.popperJS || (this.showPopper && !forceDestroy)) return;
			// this.popperJS.destroy();
			// this.popperJS = null;
		},
		generateId() {
			return Math.floor(Math.random() * 10000);
		},
	},

	beforeDestroy() {
		this.popperVM && this.popperVM.$destroy();
	},

	destroyed() {
		const reference = this.referenceElm;
		if (reference.nodeType === 1) {
			off(reference, "mouseenter", this.show);
			off(reference, "mouseleave", this.hide);
			off(reference, "focus", this.handleFocus);
			off(reference, "blur", this.handleBlur);
			off(reference, "click", this.removeFocusing);
		}
	},
};
